package user

import (
    "gitee.com/zwx784533/zwx2018/app"
    "strconv"
    "gitee.com/zwx784533/zwx2018/model"
    "encoding/json"
    "github.com/garyburd/redigo/redis"
    "strings"
    "gitee.com/zwx784533/zwx2018/utils"
    "gitee.com/zwx784533/zwx2018/utils/qcloud"
    "time"
)

// 获取某个用户的公开信息
func GetUserPublicInfo(c *app.Context)  {
    var userID int
    var idErr error
    if userID, idErr = strconv.Atoi(c.Param("id")); idErr != nil {
        c.ErrorResponse(0, idErr.Error())
        return
    }
    // read from redis
    pool, err := model.GetRedisPool("user")
    if err != nil {
        c.ErrorResponse(0, err.Error())
        go app.Error(err)
        return
    }
    user := &model.User{}
    // redisClient
    rc := pool.Get()
    defer rc.Close()
    cacheData, err := redis.String(rc.Do("hGet", "user_info", userID))
    if err != nil {
        app.Error("redis err:", err)
    } else if cacheData != "" {
        err = json.Unmarshal([]byte(cacheData), &user)
        if err != nil {
            c.ErrorResponse(0, err.Error())
            return
        }
        c.ResponseJson(0, app.Obj{"user": user})
        go app.Info("read from redis")
        return
    }

    user, err = model.GetUserData(userID)
    if err != nil {
        c.ErrorResponse(500, err.Error())
        return
    }
    jsonBytes, _ := json.Marshal(user)
    _, err = rc.Do("hSet", "user_info", userID,  string(jsonBytes))
    if err != nil {
        go app.Error("hset error:", err)
    }

    go app.Info("read from db")
    c.ResponseJson(0, app.Obj{"user": user})
    return
}

// 登录
func Login(c *app.Context)  {
    // 定义body的数据结构
    type LoginForm struct {
        Email string `json:"email"`
        Password string `json:"password"`
    }
    // 声明接收body数据的变量
    var loginData LoginForm
    // 获取 body 数据
    err := c.GetRawData(&loginData)
    if err != nil {
        go app.Error("admin login error: ", err)
        c.ErrorResponse(400, err.Error())
        return
    }
    if utils.CheckEmailFormat(loginData.Email) == false {
        c.ErrorResponse(400, "邮箱格式错误")
        return
    }
    user, err := model.LoginByEmail(loginData.Email, loginData.Password)
    if err != nil {
        go app.Error("admin login error: ", err)
        c.ErrorResponse(500, err.Error())
        return
    }
    c.ResponseJson(0, app.Obj{"user": user, "token": user.LastToken})
}

// 获取登录用户的信息
func GetUserInfo(c *app.Context) {
    var userID int

    userID = c.Uid
    // read from redis
    pool, err := model.GetRedisPool("user")
    if err != nil {
        c.ErrorResponse(500, err.Error())
        go app.Error(err)
        return
    }
    user := &model.User{}
    // redisClient
    rc := pool.Get()
    defer rc.Close()
    cacheData, err := redis.String(rc.Do("hGet", "user_info", userID))
    if err != nil {
        app.Error("redis err:", err)
    } else if cacheData != "" {
        err = json.Unmarshal([]byte(cacheData), &user)
        if err != nil {
            c.ErrorResponse(500, err.Error())
            return
        }
        c.ResponseJson(0, app.Obj{"user": user})
        go app.Info("read from redis")
        return
    }

    user, err = model.GetUserData(userID)
    if err != nil {
        c.ErrorResponse(500, err.Error())
        return
    }
    jsonBytes, _ := json.Marshal(user)
    _, err = rc.Do("hSet", "user_info", userID,  string(jsonBytes))
    if err != nil {
        go app.Error("hset error:", err)
    }

    go app.Info("read from db")
    c.ResponseJson(0, app.Obj{"user": user})
    return
}

// 
func Register(c *app.Context)  {
    // 定义body的数据结构
    type LoginForm struct {
        Email string `json:"email"`
        Password string `json:"password"`
        ConfirmPassword string `json:"confirm_password"`
    }
    // 声明接收body数据的变量
    var data LoginForm
    // 获取 body 数据
    err := c.GetRawData(&data)
    if err != nil {
        go app.Error("register error: ", err)
        c.ErrorResponse(400, err.Error())
        return
    }
    if utils.CheckEmailFormat(data.Email) == false {
        c.ErrorResponse(400, "邮箱格式错误")
        return
    }
    if len(data.Password) < 6 {
        c.ErrorResponse(400, "密码长度应不少于6位")
        return
    }
    if data.Password != data.ConfirmPassword {
        c.ErrorResponse(400, "两次密码不一致")
        return
    }
    loginData, err := model.GetLoginData(data.Email, model.UserIdSourceEmail)
    if err != nil {
        c.ErrorResponse(500, err.Error())
        return
    }
    if loginData.Uid != 0 {
        c.ErrorResponse(400, "该邮箱已被注册")
        return
    }
    user, err := model.CreateUser(data.Email, model.UserIdSourceEmail, data.Password, "")
    if err != nil {
        go app.Error("admin login error: ", err)
        c.ErrorResponse(500, err.Error())
        return
    }
    c.ResponseJson(0, app.Obj{"user": user, "token": user.LastToken})
}

func UpdateProfile(c *app.Context)  {
    type postData struct {
        Nick string `json:"nick"`
        Avatar string `json:"avatar"`
        Bio string `json:"bio"`
    }
    var data postData
    err := c.GetRawData(&data)
    if err != nil {
        c.ErrorResponse(400, err.Error())
        return
    }
    if len(data.Nick) == 0 {
        c.ErrorResponse(400, "昵称不能为空")
        return
    }
    if len(data.Nick) > 20 {
        c.ErrorResponse(400, "昵称长度超过限制，最长20个字符")
        return
    }
    if len(data.Bio) > 200 {
        c.ErrorResponse(400, "个人简介长度超过限制，最长200个字符")
        return
    }
    if len(data.Avatar) > 255 {
        c.ErrorResponse(400, "头像地址错误")
        return
    }
    if len(data.Avatar) > 0 && strings.Index(data.Avatar, "http") < 0 {
        c.ErrorResponse(400, "头像地址错误")
        return
    }
    
    user, err := model.GetUserData(c.Uid)
    if err != nil || user == nil {
        c.ErrorResponse(400, "用户不存在")
        return
    }
    user.Nick = data.Nick
    user.Avatar = data.Avatar
    user.Bio = data.Bio
    err = user.Save()
    if err != nil {
        go app.Error("updateProfile: error: ", err)
        c.ErrorResponse(500, "服务器错误")
        return
    }
    // 删除缓存
    model.DelUserCache(user.Uid)

    c.ResponseJson(0, app.Obj{})
}

func GetQcloudSignature(c *app.Context)  {
    sign, err := qcloud.GetTmpSign()
    if err != nil {
        go app.Error("updateProfile: error: ", err)
        c.ErrorResponse(500, "服务器错误")
        return
    }
    c.ResponseJson(0, app.Obj{"sign": sign, "expiredTime": time.Now().Unix()+1800})
}